Dart _fe_analyzer_shared parser Parser

用于解析 Dart 程序的事件生成解析器。这个解析器预期所有的令牌都在一个链表(即令牌流,Token)中,由类 Scanner 生成一个令牌流。

该类会抛出事件,由 Listener 类的子类用于监听事件。

这个类的大多数方法属于四个主要类别之一:

解析方法:

解析方法都有前缀 parse,通过调用 listener 上的方法来生成事件,并返回下一个要解析的令牌。一些例外,如 parseFunctionBody 和 parseClassOrMixinOrExtensionBody 等方法返回的是最后一个解析的令牌,而不是下一个要解析的令牌。解析方法通常命名为 parseGrammarProductionSuffix。后缀可以是 optstaropt 表示零个或一个匹配,star 表示零个或多个匹配。例如,parseMetadataStar 对应于语法片段:metadata*,而 parseArgumentsOpt 对应于:arguments?

窥视方法都有前缀 peek,不生成事件(除了错误),并且可能返回 null。

确保方法都有前缀 ensure 并且可能会生成事件。如果当前令牌不匹配,它们会返回当前令牌,或插入并返回一个合成令牌。例如,ensureSemicolon 会在当前令牌是分号的情况下返回当前令牌,否则在当前令牌之前插入一个合成分号到令牌流中,然后返回那个新的合成令牌。

跳过方法类似于解析方法,但都有 skip 前缀,并跳过被解析文件的某些部分。通常,跳过方法会为被跳过的结构生成一个事件,但不为其子结构生成。

当前令牌

当前令牌始终可以在名为 token 的正式参数中找到。这个参数应该是第一个,因为这增加了编译器将其放在寄存器中的机会。

实现说明

解析器假定关键字、内置标识符和其他特殊单词(伪关键字)都是规范化的。要扩展解析器以识别新的标识符,应该修改 keyword.dart 并确保标识符被添加到关键字表中。

因此,不应该在解析器中使用 == 来比较字符串。应该更倾向于使用方法 optional 和 expect 来识别关键字或标识符。在某些情况下,可以使用 identical 来比较令牌的 stringValue,但通常 optional 就足够了。

从历史上看,我们过度使用了 identical,而当在非字符串对象上使用 identical 时,通常可以被 == 替代。

灵活性、可扩展性和规范性

解析器旨在灵活和可扩展。它的方法被设计为可以在子类中被覆盖,因此可以扩展来处理未规定的语言扩展或实验,同时这个文件中的所有内容都尝试遵循规范(除非它干扰到错误恢复)。

我们通过遵循几个经验法则来实现灵活性、可扩展性和规范性:

  1. 解析器中的所有方法应该是公开的。

  2. 方法遵循指定的语法,并不实现自定义扩展,例如 native

  3. 解析器不重写令牌流(处理 >>除外)。

解析器不生成抽象语法树(AST),这是 [Listener] 的职责。

解析器不应该过度假设 [Listener] 的行为。

Parser 中的 listener

Listener 是 Parser 中的一个类属性,扮演了很重要的作用。该属性由外部通过构造函数传入。

parseUnit

parseUnitParser 类中的一个方法,它的主要任务是解析一个编译单元。在 Dart 中,一个编译单元通常对应一个源文件。

主要步骤:

  1. 首先,它跳过并记录所有的错误令牌,以便在最后报告。

  2. 然后,它调用 listener.beginCompilationUnit 方法来通知监听器开始解析一个新的编译单元。

  3. 接下来,它创建一个 DirectiveContext 对象,用于跟踪解析过程中的指令状态。

  4. 然后,它检查下一个令牌是否是脚本标签(#!)。如果是,它会解析这个脚本标签。

  5. 接下来,它进入一个循环,不断解析顶级声明,直到遇到文件结束(EOF)令牌。

  6. 在每次解析完一个顶级声明后,它都会调用 listener.endTopLevelDeclaration 方法来通知监听器结束解析一个顶级声明。

  7. 如果在解析过程中没有进展(即当前令牌和下一个令牌相同),那么它会报告一个可恢复的错误,并跳过当前令牌。

  8. 在解析完所有的顶级声明后,它会调用 listener.endCompilationUnit 方法来通知监听器结束解析这个编译单元。

  9. 最后,它会报告所有之前跳过的错误令牌,并清除可能导致内存泄漏的字段。

这个方法的主要作用是解析一个编译单元,这是编译器前端的一个重要步骤。


本文作者:Maeiee

本文链接:Dart _fe_analyzer_shared parser Parser

版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!


喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!